//
//  TrackTool.m
//  location
//
//  Created by Dongxiang Xu on 2025/8/28.
//

#import "TrackTool.h"

@implementation TrackTool

#pragma mark - 按照activity重新分组
+ (NSMutableArray *)sortFormartArray:(NSMutableArray *)array
{
    NSMutableArray *tempArray = [NSMutableArray array];
    for (NSMutableArray *arr in array) {
        for (NSMutableDictionary *dic in arr) {
            [tempArray addObject:dic];
        }
    }
 
    NSMutableArray *activityArray = [NSMutableArray array];
    NSString *activity = @"";
    for (NSMutableDictionary *dic in tempArray) {
        if ([activity isEqualToString:dic[@"activity"]]) {
            [activityArray.lastObject addObject:dic];
        }else{
            activity = dic[@"activity"];
            if ([activityArray.lastObject count]==1) {
                [activityArray removeLastObject];
                if ([[activityArray.lastObject lastObject][@"activity"] isEqualToString:dic[@"activity"]]) {
                    [activityArray.lastObject addObject:dic];
                }else{
                    NSMutableArray *array = [NSMutableArray array];
                    [array addObject:dic];
                    [activityArray addObject:array];
                }
            }else{
                NSMutableArray *array = [NSMutableArray array];
                [array addObject:dic];
                [activityArray addObject:array];
            }
        }
    }
    if (activityArray.count>1) {
        NSMutableArray *tempArray = [NSMutableArray array];
        for (NSMutableArray *array in activityArray) {
            for (NSMutableDictionary *dic in array) {
                [tempArray addObject:dic];
            }
        }
        activityArray = [NSMutableArray array];
        activity = @"";
        for (NSMutableDictionary *dic in tempArray) {
            if ([activity isEqualToString:dic[@"activity"]]) {
                [activityArray.lastObject addObject:dic];
            }else{
                activity = dic[@"activity"];
                if ([activityArray.lastObject count]==1) {
                    [activityArray removeLastObject];
                    if ([[activityArray.lastObject lastObject][@"activity"] isEqualToString:dic[@"activity"]]) {
                        [activityArray.lastObject addObject:dic];
                    }else{
                        NSMutableArray *array = [NSMutableArray array];
                        [array addObject:dic];
                        [activityArray addObject:array];
                    }
                }else{
                    NSMutableArray *array = [NSMutableArray array];
                    [array addObject:dic];
                    [activityArray addObject:array];
                }
            }
        }
    }
    return activityArray;
}

#pragma mark - 定位点为静止状态（之前为运动），但是一直在位移，优化为运动状态，定位点为运动状态，如果移动半径没有两次及以上超过150m，则优化为静止状态
+ (NSMutableArray *)staticActivityToMovieWithArray:(NSMutableArray *)aArray
{
    NSMutableArray *resultArray;
    NSMutableArray *array = [NSMutableArray arrayWithArray:aArray];
    if (array.count>0) {
        for (int i = 0; i < array.count; i ++) {
            NSMutableArray *arr = array[i];
            if ([arr.firstObject[@"activity"] isEqualToString:@"静止"] && arr.count>2) {
                double distanceTotal = 0;
                NSMutableArray *indexArray = [NSMutableArray array];

                
                // 判断静止段中有2次及以上的位移超过150m，则记录下开始位移的下标index，一旦位移小于150m，记录下结束下标toIndex
                for (int j = 1; j < arr.count; j++) {

                    double distance = [self distanceBetweenOrderByLatitudeA:[arr[j-1][@"latitude"] doubleValue] latitudeB:[arr[j][@"latitude"] doubleValue] longitudeA:[arr[j-1][@"longtitude"] doubleValue] longitudeB:[arr[j][@"longtitude"] doubleValue]];
                    distanceTotal = distanceTotal + distance;
                    if (distance>0.002) {
                        if (indexArray.count==0) {
                            [indexArray addObject:@(j)];
                        }else{
                            if ((j-[indexArray.lastObject integerValue])==1) {
                                [indexArray addObject:@(j)];
                            }
                            if (j==(arr.count-1)) {
                                if ((indexArray.count>=3 && distanceTotal>0.15) || indexArray.count>=5) {
                                    NSInteger start = [indexArray.firstObject integerValue];
                                    NSInteger end = [indexArray.lastObject integerValue];
                                    for (NSInteger j = start; j < end; j++) {
                                        NSMutableDictionary *dic = arr[j];
                                        //如果当前静止段不为最后一个阶段，则看下一个阶段的运动状态是否满足一定时常
                                        if (i<(array.count-1)) {
                                            NSArray *nextArray = array[i+1];
                                            if (nextArray.count>1) {
                                                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                                                [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                                                dateFormatter.locale = [NSLocale systemLocale];
                                                dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
                                                
                                                NSDate *firstDate = [dateFormatter dateFromString:[nextArray.firstObject[@"create_time"] substringToIndex:19]];
                                                NSInteger firstSecond = [firstDate timeIntervalSince1970];
                                                
                                                NSDate *lastDate = [dateFormatter dateFromString:[nextArray.lastObject[@"create_time"] substringToIndex:19]];
                                                NSInteger lastSecond = [lastDate timeIntervalSince1970];
                                                if ((lastSecond-firstSecond)>=ABNORMAL_DURATION) {
                                                    [dic setValue:nextArray.firstObject[@"activity"] forKey:@"activity"];
                                                }else{
                                                    [dic setValue:@"行程" forKey:@"activity"];
                                                }
                                            }else{
                                                [dic setValue:@"行程" forKey:@"activity"];
                                            }
                                        }else{
                                            [dic setValue:@"行程" forKey:@"activity"];
                                        }
                                    }
                                }
                                distanceTotal = 0;
                                [indexArray removeAllObjects];
                            }
                        }
                    }else{
                        if ((indexArray.count>=3 && distanceTotal>0.15) || indexArray.count>=5) {
                            NSInteger start = [indexArray.firstObject integerValue];
                            NSInteger end = [indexArray.lastObject integerValue];
                            for (NSInteger j = start; j < end; j++) {
                                NSMutableDictionary *dic = arr[j];
                                //如果当前静止段不为最后一个阶段，则看下一个阶段的运动状态是否满足一定时常
                                if (i<(array.count-1)) {
                                    NSArray *nextArray = array[i+1];
                                    if (nextArray.count>1) {
                                        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                                        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                                        dateFormatter.locale = [NSLocale systemLocale];
                                        dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
                                        
                                        NSDate *firstDate = [dateFormatter dateFromString:[nextArray.firstObject[@"create_time"] substringToIndex:19]];
                                        NSInteger firstSecond = [firstDate timeIntervalSince1970];
                                        
                                        NSDate *lastDate = [dateFormatter dateFromString:[nextArray.lastObject[@"create_time"] substringToIndex:19]];
                                        NSInteger lastSecond = [lastDate timeIntervalSince1970];
                                        if ((lastSecond-firstSecond)>=ABNORMAL_DURATION) {
                                            [dic setValue:nextArray.firstObject[@"activity"] forKey:@"activity"];
                                        }else{
                                            [dic setValue:@"行程" forKey:@"activity"];
                                        }
                                    }else{
                                        [dic setValue:@"行程" forKey:@"activity"];
                                    }
                                }else{
                                    [dic setValue:@"行程" forKey:@"activity"];
                                }
                            }
                        }
                        distanceTotal = 0;
                        [indexArray removeAllObjects];
                    }
                }
               
            }else if (![arr.firstObject[@"activity"] isEqualToString:@"静止"] && arr.count>=2){
                BOOL isOut500 = NO;
                for (int j = 1; j < arr.count; j++) {
                    double distance = [self distanceBetweenOrderByLatitudeA:[arr.firstObject[@"latitude"] doubleValue] latitudeB:[arr[j][@"latitude"] doubleValue] longitudeA:[arr.firstObject[@"longtitude"] doubleValue] longitudeB:[arr[j][@"longtitude"] doubleValue]];
                    
                    if (distance>0.5) {
                        isOut500 = YES;
                    }
                }
                if (isOut500==NO) {
                    for (NSInteger j = 0; j < arr.count; j++) {
                        NSMutableDictionary *dic = arr[j];
                        [dic setValue:@"静止" forKey:@"activity"];
                    }
                    
                }
            }
        }
    }
    NSMutableArray *tempArray = [NSMutableArray array];
    for (NSMutableArray *arr in array) {
        for (NSMutableDictionary *dic in arr) {
            [tempArray addObject:dic];
        }
    }
    resultArray = [NSMutableArray arrayWithArray:[self sortFormartArray:tempArray]];
    return resultArray;
}

#pragma mark - 本来连贯的状态中存在少量的异常点，优化为全程连贯状态
+ (NSMutableArray *)handleAbnormalActivityWithArray:(NSMutableArray *)aArray
{
    NSMutableArray *resultArray;
    NSMutableArray *array = [NSMutableArray arrayWithArray:aArray];
    if (array.count>0) {
        for (int i = 0; i < array.count; i ++) {
            NSMutableArray *arr = array[i];
            if (arr.count>1) {
                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                dateFormatter.locale = [NSLocale systemLocale];
                dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
                
                NSDate *firstDate = [dateFormatter dateFromString:[arr.firstObject[@"create_time"] substringToIndex:19]];
                NSInteger firstSecond = [firstDate timeIntervalSince1970];
                
                NSDate *lastDate = [dateFormatter dateFromString:[arr.lastObject[@"create_time"] substringToIndex:19]];
                NSInteger lastSecond = [lastDate timeIntervalSince1970];
                NSInteger second = lastSecond-firstSecond;
                if (second<ABNORMAL_DURATION) {
                    if (i==0) {
                        NSMutableArray *nextArr = array[i+1];
                        NSDate *firstDate = [dateFormatter dateFromString:[nextArr.firstObject[@"create_time"] substringToIndex:19]];
                        NSInteger neFirstSecond = [firstDate timeIntervalSince1970];
                        
                        NSDate *lastDate = [dateFormatter dateFromString:[nextArr.lastObject[@"create_time"] substringToIndex:19]];
                        NSInteger neLastSecond = [lastDate timeIntervalSince1970];
                        
                        NSInteger neSecond = neLastSecond-neFirstSecond;
                        if (neSecond>second && neSecond>ABNORMAL_DURATION && (neFirstSecond-lastSecond)<ABNORMAL_DURATION) {
                            for (NSInteger j = 0; j < arr.count; j++) {
                                NSMutableDictionary *dic = arr[j];
                                [dic setValue:nextArr.firstObject[@"activity"] forKey:@"activity"];
                            }
                        }else{
                            [arr removeAllObjects];
                        }
                    }else if (array.count>2 && i>0 && i<(array.count-1)){
                        NSMutableArray *nextArr = array[i+1];
                        NSDate *neFirstDate = [dateFormatter dateFromString:[nextArr.firstObject[@"create_time"] substringToIndex:19]];
                        NSInteger neFirstSecond = [neFirstDate timeIntervalSince1970];
                        
                        NSDate *neLastDate = [dateFormatter dateFromString:[nextArr.lastObject[@"create_time"] substringToIndex:19]];
                        NSInteger neLastSecond = [neLastDate timeIntervalSince1970];
                        
                        NSInteger neSecond = neLastSecond-neFirstSecond;
                        
                        NSMutableArray *foArr = array[i-1];
                        NSDate *foFirstDate = [dateFormatter dateFromString:[foArr.firstObject[@"create_time"] substringToIndex:19]];
                        NSInteger foFirstSecond = [foFirstDate timeIntervalSince1970];
                        
                        NSDate *foLastDate = [dateFormatter dateFromString:[foArr.lastObject[@"create_time"] substringToIndex:19]];
                        NSInteger foLastSecond = [foLastDate timeIntervalSince1970];
                        
                        NSInteger foSecond = foLastSecond-foFirstSecond;
                        
                        if ((neSecond>second && neSecond>ABNORMAL_DURATION && (neFirstSecond-lastSecond)<ABNORMAL_DURATION) || (foSecond>second && foSecond>ABNORMAL_DURATION && (firstSecond-foLastSecond)<ABNORMAL_DURATION)) {
                            if (neSecond>second && neSecond>ABNORMAL_DURATION && (neFirstSecond-lastSecond)<ABNORMAL_DURATION){
                                if (foSecond>second && foSecond>ABNORMAL_DURATION && (firstSecond-foLastSecond)<ABNORMAL_DURATION) {
                                    if ((neFirstSecond-lastSecond)<(firstSecond-foLastSecond)) {
                                        for (NSInteger j = 0; j < arr.count; j++) {
                                            NSMutableDictionary *dic = arr[j];
                                            [dic setValue:nextArr.firstObject[@"activity"] forKey:@"activity"];
                                        }
                                    }else{
                                        for (NSInteger j = 0; j < arr.count; j++) {
                                            NSMutableDictionary *dic = arr[j];
                                            [dic setValue:nextArr.firstObject[@"activity"] forKey:@"activity"];
                                        }
                                    }
                                }else{
                                    for (NSInteger j = 0; j < arr.count; j++) {
                                        NSMutableDictionary *dic = arr[j];
                                        [dic setValue:nextArr.firstObject[@"activity"] forKey:@"activity"];
                                    }
                                }
                            }else{
                                for (NSInteger j = 0; j < arr.count; j++) {
                                    NSMutableDictionary *dic = arr[j];
                                    [dic setValue:foArr.firstObject[@"activity"] forKey:@"activity"];
                                }
                            }
                        }else{
                            [arr removeAllObjects];
                        }
                    }else if (i==(array.count-1)){
                        NSMutableArray *foArr = array[i-1];
                        NSDate *foFirstDate = [dateFormatter dateFromString:[foArr.firstObject[@"create_time"] substringToIndex:19]];
                        NSInteger foFirstSecond = [foFirstDate timeIntervalSince1970];
                        
                        NSDate *foLastDate = [dateFormatter dateFromString:[foArr.lastObject[@"create_time"] substringToIndex:19]];
                        NSInteger foLastSecond = [foLastDate timeIntervalSince1970];
                        
                        NSInteger foSecond = foLastSecond-foFirstSecond;
                        if (foSecond>second && foSecond>ABNORMAL_DURATION && (firstSecond-foLastSecond)<ABNORMAL_DURATION) {
                            for (NSInteger j = 0; j < arr.count; j++) {
                                NSMutableDictionary *dic = arr[j];
                                [dic setValue:foArr.firstObject[@"activity"] forKey:@"activity"];
                            }
                        }else{
                            [arr removeAllObjects];
                        }
                    }
                }
            }
        }
    }
    NSMutableArray *tempArray = [NSMutableArray array];
    for (NSMutableArray *arr in array) {
        for (NSMutableDictionary *dic in arr) {
            [tempArray addObject:dic];
        }
    }
    resultArray = [NSMutableArray arrayWithArray:[self sortFormartArray:tempArray]];
    return resultArray;
}

+ (NSMutableArray *)moveActivityToStaticWithArray:(NSMutableArray *)aArray
{
    NSMutableArray *resultArray;
    NSMutableArray *array = [NSMutableArray arrayWithArray:aArray];
    if (array.count>0) {
        for (int i = 0; i < array.count; i ++) {
            NSMutableArray *arr = array[i];
            if (![arr.firstObject[@"activity"] isEqualToString:@"静止"]) {
                BOOL isOut500 = NO;
                for (int j = 1; j < arr.count; j++) {
                    double distance = [self distanceBetweenOrderByLatitudeA:[arr.firstObject[@"latitude"] doubleValue] latitudeB:[arr[j][@"latitude"] doubleValue] longitudeA:[arr.firstObject[@"longtitude"] doubleValue] longitudeB:[arr[j][@"longtitude"] doubleValue]];
                    if (distance>0.5) {
                        isOut500 = YES;
                    }
                }
                if (isOut500==NO) {
                    for (NSInteger j = 0; j < arr.count; j++) {
                        NSMutableDictionary *dic = arr[j];
                        [dic setValue:@"静止" forKey:@"activity"];
                    }
                    
                }
            }
        }
    }
    NSMutableArray *tempArray = [NSMutableArray array];
    for (NSMutableArray *arr in array) {
        for (NSMutableDictionary *dic in arr) {
            [tempArray addObject:dic];
        }
    }
    resultArray = [NSMutableArray arrayWithArray:[self sortFormartArray:tempArray]];
    return resultArray;
}


+ (NSMutableArray *)moveActivityToDriveWithArray:(NSMutableArray *)aArray
{
    NSMutableArray *resultArray;
    NSMutableArray *array = [NSMutableArray arrayWithArray:aArray];
    if (array.count>0) {
        for (int i = 0; i < array.count; i ++) {
            NSMutableArray *arr = array[i];
            if ([arr.firstObject[@"activity"] isEqualToString:@"行程"]) {
                CGFloat totalDistance = 0;
                NSMutableArray *driveSpeedArray = [NSMutableArray array];
                for (int j = 1; j < arr.count; j++) {
                    double distance = [self distanceBetweenOrderByLatitudeA:[arr[j-1][@"latitude"] doubleValue] latitudeB:[arr[j][@"latitude"] doubleValue] longitudeA:[arr[j-1][@"longtitude"] doubleValue] longitudeB:[arr[j][@"longtitude"] doubleValue]];
                    totalDistance = totalDistance+distance;
                    if ([arr[j][@"speed"] floatValue]>=20) {
                        [driveSpeedArray addObject:arr[j]];
                    }
                }
                if ((totalDistance>=1.0 && driveSpeedArray.count>=5) || (totalDistance>=3.0 && driveSpeedArray.count>=8) || (totalDistance>=10 && driveSpeedArray.count>=10)) {
                    for (NSInteger j = 0; j < arr.count; j++) {
                        NSMutableDictionary *dic = arr[j];
                        [dic setValue:@"驾车" forKey:@"activity"];
                    }
                }
            }
        }
    }

    resultArray = [NSMutableArray arrayWithArray:array];
    return resultArray;
}

+ (double)distanceBetweenOrderByLatitudeA:(double)latitude1 latitudeB:(double)latitude2 longitudeA:(double)longitude1 longitudeB:(double)longitude2
{
    CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1];
    CLLocation *otherLocation = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2];
    double  distance = [curLocation distanceFromLocation:otherLocation]/1000;
    return  distance;
}

+ (void)getStaticStartTimeWithData:(NSArray *)data
                              Date:(NSString *)date
                          Yestoday:(void (^)(id _Nullable))yestoday
{
    NSMutableArray *array = [NSMutableArray array];
    NSMutableDictionary *tempDic;
    for (NSDictionary *dict in data) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:dict];
        [dic setValue:dict[@"createTime"] forKey:@"create_time"];
        [dic setValue:dict[@"longitude"] forKey:@"longtitude"];
        if ([dict[@"activity"] integerValue]==0 || [dict[@"activity"] integerValue]==1) {
            [dic setValue:@"静止" forKey:@"activity"];
        }else if ([dict[@"activity"] integerValue]==4){
            [dic setValue:@"驾车" forKey:@"activity"];
        }else{
            [dic setValue:@"行程" forKey:@"activity"];
        }
        
        if (tempDic) {
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            dateFormatter.locale = [NSLocale systemLocale];
            dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
            
            NSDate *tempDate = [dateFormatter dateFromString:[tempDic[@"create_time"] substringToIndex:19]];
            NSInteger tempSecond = [tempDate timeIntervalSince1970];
            
            NSDate *dicDate = [dateFormatter dateFromString:[dic[@"create_time"] substringToIndex:19]];
            NSInteger dicSecond = [dicDate timeIntervalSince1970];
            if ((dicSecond-tempSecond)>600) {
                NSMutableDictionary *aaDic = [NSMutableDictionary dictionary];
                [aaDic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                [aaDic setValue:@"0" forKey:@"unlock"];
                [aaDic setValue:@"0" forKey:@"notify_log"];
                [aaDic setValue:tempDic[@"latitude"] forKey:@"latitude"];
                [aaDic setValue:tempDic[@"longtitude"] forKey:@"longtitude"];
                [aaDic setValue:tempDic[@"create_time"] forKey:@"create_time"];
                [aaDic setValue:@"静止" forKey:@"activity"];
                [aaDic setValue:@"0" forKey:@"speed"];
                [array addObject:aaDic];
                
                NSMutableDictionary *aDic = [NSMutableDictionary dictionary];
                [aDic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                [aDic setValue:@"0" forKey:@"unlock"];
                [aDic setValue:@"0" forKey:@"notify_log"];
                [aDic setValue:tempDic[@"latitude"] forKey:@"latitude"];
                [aDic setValue:tempDic[@"longtitude"] forKey:@"longtitude"];
                [aDic setValue:dic[@"create_time"] forKey:@"create_time"];
                [aDic setValue:@"静止" forKey:@"activity"];
                [aDic setValue:@"0" forKey:@"speed"];
                [array addObject:aDic];
            }
        }
        tempDic = [NSMutableDictionary dictionaryWithDictionary:dic];
        [array addObject:dic];
    }
    if (array.count>0) {
        if (![array.firstObject[@"create_time"] containsString:@"00:00"]) {
            if (![array.firstObject[@"activity"] isEqualToString:@"静止"]) {
                if ([[array.firstObject[@"create_time"] substringWithRange:NSMakeRange(11, 2)] integerValue]>1) {
                    {
                        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
                        [dic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                        [dic setValue:@"0" forKey:@"unlock"];
                        [dic setValue:@"0" forKey:@"notify_log"];
                        [dic setValue:array.firstObject[@"latitude"] forKey:@"latitude"];
                        [dic setValue:array.firstObject[@"longtitude"] forKey:@"longtitude"];
                        [dic setValue:array.firstObject[@"create_time"] forKey:@"create_time"];
                        [dic setValue:@"静止" forKey:@"activity"];
                        [dic setValue:@"静止" forKey:@"org_activity"];
                        [dic setValue:@"0" forKey:@"speed"];
                        [array insertObject:dic atIndex:0];
                    }
                    {
                        NSMutableDictionary *dic = [NSMutableDictionary dictionary];
                        [dic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                        [dic setValue:@"0" forKey:@"unlock"];
                        [dic setValue:@"0" forKey:@"notify_log"];
                        [dic setValue:array.firstObject[@"latitude"] forKey:@"latitude"];
                        [dic setValue:array.firstObject[@"longtitude"] forKey:@"longtitude"];
                        [dic setValue:[array.firstObject[@"create_time"] stringByReplacingCharactersInRange:NSMakeRange(11, 8) withString:@"00:00:00"] forKey:@"create_time"];
                        [dic setValue:@"静止" forKey:@"activity"];
                        [dic setValue:@"静止" forKey:@"org_activity"];
                        [dic setValue:@"0" forKey:@"speed"];
                        [array insertObject:dic atIndex:0];
                    }
                }else{
                    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
                    [dic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                    [dic setValue:@"0" forKey:@"unlock"];
                    [dic setValue:@"0" forKey:@"notify_log"];
                    [dic setValue:array.firstObject[@"latitude"] forKey:@"latitude"];
                    [dic setValue:array.firstObject[@"longtitude"] forKey:@"longtitude"];
                    [dic setValue:[array.firstObject[@"create_time"] stringByReplacingCharactersInRange:NSMakeRange(11, 8) withString:@"00:00:00"] forKey:@"create_time"];
                    [dic setValue:array.firstObject[@"speed"] forKey:@"speed"];
                    [dic setValue:@"行程" forKey:@"activity"];
                    [dic setValue:dic[@"activity"] forKey:@"org_activity"];
                    [array insertObject:dic atIndex:0];
                }
            }else{
                NSMutableDictionary *dic = [NSMutableDictionary dictionary];
                [dic setValue:[XDXTimeTool getNowTimeTimestamp] forKey:@"id"];
                [dic setValue:@"0" forKey:@"unlock"];
                [dic setValue:@"0" forKey:@"notify_log"];
                [dic setValue:array.firstObject[@"latitude"] forKey:@"latitude"];
                [dic setValue:array.firstObject[@"longtitude"] forKey:@"longtitude"];
                [dic setValue:[array.firstObject[@"create_time"] stringByReplacingCharactersInRange:NSMakeRange(11, 8) withString:@"00:00:00"] forKey:@"create_time"];
                [dic setValue:@"静止" forKey:@"activity"];
                [dic setValue:dic[@"activity"] forKey:@"org_activity"];
                [dic setValue:@"0" forKey:@"speed"];
                [array insertObject:dic atIndex:0];
            }
        }
            
        NSMutableArray *tempArray = [TrackTool segmentsFromLocationArray:array];
        tempArray = [TrackTool sortFormartArray:tempArray];
        tempArray = [TrackTool moveActivityToDriveWithArray:tempArray];
        
        if (tempArray.count>0) {
            NSMutableArray *activityArray = [NSMutableArray array];
            for (NSInteger j=0; j<tempArray.count; j++) {
                NSArray *array = tempArray[j];
                if (array.count>1) {
                    [activityArray addObject:array];
                }
            }
            
            if (activityArray.count>0) {
                for (NSInteger j = (activityArray.count-1); j>=0; j --) {
                    NSArray *array = activityArray[j];
                    if (![array.lastObject[@"activity"] isEqualToString:@"静止"]) {
                        yestoday(array.lastObject[@"create_time"]);
                        break;
                    }else{
                        // 需要追溯前一天的状态
                        if (activityArray.count==1) {
                            // 如果为今天，返回&代表需要追述昨天，并且返回时间
                            if ([[XDXTimeTool currentDate] containsString:date]) {
                                yestoday([NSString stringWithFormat:@"&%@",array.firstObject[@"create_time"]]);
                            }else{
                                yestoday(array.firstObject[@"create_time"]);
                            }
                           
                        }else{
                            yestoday(array.firstObject[@"create_time"]);
                        }
                        break;
                    }
                }
            }else{
                // 需要追溯前一天的状态
                // 如果为今天，返回空字符串，追述昨天
                if ([[XDXTimeTool currentDate] containsString:date]) {
                    yestoday(@"");
                }else{
                    yestoday(nil);
                }
            }
        }else{
            // 需要追溯前一天的状态
            // 如果为今天，返回空字符串，追述昨天
            if ([[XDXTimeTool currentDate] containsString:date]) {
                yestoday(@"");
            }else{
                yestoday(nil);
            }
        }
        
    }else{
        // 需要追溯前一天的状态
        // 如果为今天，返回空字符串，追述昨天
        if ([[XDXTimeTool currentDate] containsString:date]) {
            yestoday(@"");
        }else{
            yestoday(nil);
        }
    }
}

// 基于经纬度与时间将点分段为“静止/行程”，仅返回二维 segments（每段为原始点字典数组）
// 仅使用 latitude、longtitude/longitude 与 create_time，不依赖 activity/speed
+ (NSMutableArray<NSArray<NSDictionary *> *> *)segmentsFromLocationArray:(NSArray<NSDictionary *> *)records
{
    if (records.count == 0) {
        return @[].mutableCopy;
    }

    // 常量（单位：距离km、时间秒）
    const double enterRadiusKm = 0.10;    // 100m
    const double exitRadiusKm  = 0.15;    // 200m，迟滞，避免抖动
    const NSTimeInterval minStopDurationSec = 5 * 60;   // 5分钟
    const NSTimeInterval minTripDurationSec = 2 * 60;   // 2分钟
    const double minTripDistanceKm = 0.15;               // 150米
    const NSTimeInterval maxHardGapSec = 30 * 60;       // 超长间隔强制切段
    const NSTimeInterval manualStopGapSec = 30 * 60;    // >1800s 插入一段静止（插入型）

    // 时间解析器
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    dateFormatter.locale = [NSLocale systemLocale];
    dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierISO8601];

    // 1) 规范化并排序：[{lat, lon, t, orig}]
    NSMutableArray<NSDictionary *> *points = [NSMutableArray arrayWithCapacity:records.count];
    for (NSDictionary *rec in records) {
        id latVal = rec[@"latitude"];
        id lonVal = rec[@"longtitude"] ?: rec[@"longitude"];
        id timeVal = rec[@"create_time"] ?: rec[@"createTime"];
        if (!latVal || !lonVal || !timeVal || latVal == (id)kCFNull || lonVal == (id)kCFNull || timeVal == (id)kCFNull) {
            continue;
        }

        double lat = [latVal doubleValue];
        double lon = [lonVal doubleValue];
        if (!(lat <= 90 && lat >= -90) || !(lon <= 180 && lon >= -180)) {
            continue; // 坐标异常
        }

        NSTimeInterval tSec = 0;
        if ([timeVal isKindOfClass:[NSString class]]) {
            NSString *ts = (NSString *)timeVal;
            if (ts.length >= 19) {
                ts = [ts substringToIndex:19];
                NSDate *d = [dateFormatter dateFromString:ts];
                if (!d) { continue; }
                tSec = [d timeIntervalSince1970];
            } else {
                double v = [ts doubleValue];
                if (v > 1e12) {
                    tSec = v / 1000.0; // 毫秒
                } else {
                    tSec = v; // 秒
                }
            }
        } else if ([timeVal isKindOfClass:[NSNumber class]]) {
            double v = [(NSNumber *)timeVal doubleValue];
            if (v > 1e12) {
                tSec = v / 1000.0;
            } else {
                tSec = v;
            }
        } else {
            continue;
        }

        [points addObject:@{ @"lat": @(lat), @"lon": @(lon), @"t": @(tSec), @"orig": rec }];
    }

    if (points.count == 0) {
        return @[].mutableCopy;
    }

    [points sortUsingComparator:^NSComparisonResult(NSDictionary *a, NSDictionary *b) {
        NSTimeInterval ta = [a[@"t"] doubleValue];
        NSTimeInterval tb = [b[@"t"] doubleValue];
        if (ta < tb) return NSOrderedAscending;
        if (ta > tb) return NSOrderedDescending;
        return NSOrderedSame;
    }];
    points = [[self class] xdxFilterSpikePoints:points];
    

    typedef NS_ENUM(NSInteger, XDXSegState) { XDXSegStateMoving = 0, XDXSegStateStop = 1 };
    XDXSegState state = XDXSegStateMoving;

    NSMutableArray<NSMutableArray<NSDictionary *> *> *segments = [NSMutableArray array]; // 标准化点二维
    NSMutableArray<NSString *> *types = [NSMutableArray array]; // "stop" / "trip"

    NSMutableArray<NSDictionary *> *moving = [NSMutableArray array];            // 行程点（已确定）
    NSMutableArray<NSDictionary *> *pending = [NSMutableArray array];           // 候选静止窗口点
    NSMutableArray<NSDictionary *> *stopping = [NSMutableArray array];          // 静止段点

    __block NSDictionary *anchor = nil;       // 候选静止锚点
    NSDictionary *stopCenter = nil;   // 静止中心（采用进入静止时的 anchor）

    NSTimeInterval lastTime = [[points.firstObject objectForKey:@"t"] doubleValue];

    // 检测静止段中的点是否呈现明显的移动模式
    // 优化目标：在exitRadiusKm范围内，如果点呈现有序移动而非分散无序状态，应归类为行程
    BOOL (^isMovingPatternInStop)(NSArray<NSDictionary *> *) = ^BOOL(NSArray<NSDictionary *> *stoppingPoints) {
        if (stoppingPoints.count < 3) return NO;
        
        // 计算移动方向的一致性
        NSMutableArray<NSNumber *> *directions = [NSMutableArray array];
        double totalDistance = 0.0;
        NSTimeInterval totalTime = 0.0;
        
        for (NSInteger i = 1; i < stoppingPoints.count; i++) {
            NSDictionary *prev = stoppingPoints[i-1];
            NSDictionary *curr = stoppingPoints[i];
            
            double lat1 = [prev[@"lat"] doubleValue];
            double lon1 = [prev[@"lon"] doubleValue];
            double lat2 = [curr[@"lat"] doubleValue];
            double lon2 = [curr[@"lon"] doubleValue];
            
            // 计算距离
            double dist = [TrackTool distanceBetweenOrderByLatitudeA:lat1 latitudeB:lat2 longitudeA:lon1 longitudeB:lon2];
            totalDistance += dist;
            
            // 计算时间差
            NSTimeInterval timeDiff = [curr[@"t"] doubleValue] - [prev[@"t"] doubleValue];
            totalTime += timeDiff;
            
            // 计算方向角度
            double deltaLat = lat2 - lat1;
            double deltaLon = lon2 - lon1;
            double angle = atan2(deltaLon, deltaLat) * 180.0 / M_PI;
            [directions addObject:@(angle)];
        }
        
        // 参数1：最小移动距离阈值 - 如果总移动距离很小，认为是静止
        const double minMovingDistanceKm = 0.05; // 50米
        if (totalDistance < minMovingDistanceKm) return NO;
        
        // 参数2：速度阈值 - 计算平均移动速度
        if (totalTime > 0) {
            double avgSpeed = totalDistance / (totalTime / 3600.0); // km/h
            const double minMovingSpeedKmh = 0.5; // 0.5km/h
            if (avgSpeed > minMovingSpeedKmh) return YES;
        }
        
        // 参数3：方向一致性阈值 - 计算方向变化的标准差
        double meanAngle = 0.0;
        for (NSNumber *angle in directions) {
            meanAngle += [angle doubleValue];
        }
        meanAngle /= directions.count;
        
        double variance = 0.0;
        for (NSNumber *angle in directions) {
            double diff = [angle doubleValue] - meanAngle;
            // 处理角度环绕问题
            while (diff > 180) diff -= 360;
            while (diff < -180) diff += 360;
            variance += diff * diff;
        }
        variance /= directions.count;
        double stdDev = sqrt(variance);
        
        // 综合判断：方向变化标准差较小且移动距离足够，说明移动方向相对一致，认为是移动状态
        const double maxDirectionStdDev = 90.0; // 90度以内的方向变化认为是移动
        return stdDev < maxDirectionStdDev && totalDistance > minMovingDistanceKm;
    };

    // 辅助：将数组写入段
    void (^flushMoving)(void) = ^{
        if (moving.count > 0) {
            [segments addObject:[moving mutableCopy]];
            [types addObject:@"trip"];
            [moving removeAllObjects];
        }
    };
    void (^flushStopping)(void) = ^{
        if (stopping.count > 0) {
            [segments addObject:[stopping mutableCopy]];
            [types addObject:@"stop"];
            [stopping removeAllObjects];
        }
    };
    // 将 pending 归并到 moving（用于候选失败或强制切段）
    void (^drainPendingToMoving)(void) = ^{
        if (pending.count > 0) {
            [moving addObjectsFromArray:pending];
            [pending removeAllObjects];
            anchor = nil;
        }
    };

    for (NSInteger i = 0; i < points.count; i++) {
        NSDictionary *p = points[i];
        NSTimeInterval t = [p[@"t"] doubleValue];

        // 超长时间间隔：插入型“静止”段（仅含两端点），同时也作为强制切段
        if (t - lastTime > manualStopGapSec) {
            if (state == XDXSegStateStop) {
                flushStopping();
                state = XDXSegStateMoving;
            }
            drainPendingToMoving();
            flushMoving();

            // 插入一段只含两端点的静止段（端点重复出现于各自原段与此插入段）
            NSDictionary *prev = points[i-1];
            NSMutableArray *manualStopSeg = [NSMutableArray arrayWithCapacity:2];
            [manualStopSeg addObject:prev];
            [manualStopSeg addObject:p];
            [segments addObject:manualStopSeg];
            [types addObject:@"stop"];

            // 重新开始候选窗口于当前点
            [pending removeAllObjects];
            anchor = p;
            [pending addObject:p];
            stopCenter = nil;
            lastTime = t;
            continue;
        } else if (t - lastTime > maxHardGapSec) {
            // 保留原有强制切段（不插段）
            if (state == XDXSegStateStop) {
                flushStopping();
                state = XDXSegStateMoving;
            }
            drainPendingToMoving();
            flushMoving();
            [pending removeAllObjects];
            anchor = p;
            [pending addObject:p];
            stopCenter = nil;
            lastTime = t;
            continue;
        }

        if (state == XDXSegStateMoving) {
            if (pending.count == 0) {
                anchor = p;
                [pending addObject:p];
            } else {
                double dAnchor = [TrackTool distanceBetweenOrderByLatitudeA:[anchor[@"lat"] doubleValue]
                                                               latitudeB:[p[@"lat"] doubleValue]
                                                               longitudeA:[anchor[@"lon"] doubleValue]
                                                               longitudeB:[p[@"lon"] doubleValue]]; // km
                if (dAnchor <= enterRadiusKm) {
                    [pending addObject:p];
                    NSTimeInterval windowSec = [p[@"t"] doubleValue] - [anchor[@"t"] doubleValue];
                    if (windowSec >= minStopDurationSec) {
                        // 成功进入静止：先结束前一行程段，再开始静止段
                        flushMoving();
                        [stopping addObjectsFromArray:pending];
                        [pending removeAllObjects];
                        stopCenter = anchor;
                        state = XDXSegStateStop;
                    }
                } else {
                    // 候选失败，归入行程
                    drainPendingToMoving();
                    anchor = p;
                    [pending addObject:p];
                }
            }
        } else { // XDXSegStateStop
            if (!stopCenter) { stopCenter = p; }
            double dCenter = [TrackTool distanceBetweenOrderByLatitudeA:[stopCenter[@"lat"] doubleValue]
                                                           latitudeB:[p[@"lat"] doubleValue]
                                                           longitudeA:[stopCenter[@"lon"] doubleValue]
                                                           longitudeB:[p[@"lon"] doubleValue]]; // km
            if (dCenter <= exitRadiusKm) {
                // 新增：检查静止段是否呈现移动模式
                NSMutableArray *testStopping = [stopping mutableCopy];
                [testStopping addObject:p];
                
                // 只有当静止段点数达到一定数量时才进行移动检测，避免频繁检测
                if (testStopping.count >= 3 && isMovingPatternInStop(testStopping)) {
                    // 如果呈现移动模式，离开静止状态
                    flushStopping();
                    state = XDXSegStateMoving;
                    [pending removeAllObjects];
                    anchor = p;
                    [pending addObject:p];
                    stopCenter = nil;
                } else {
                    // 保持静止状态
                    [stopping addObject:p];
                }
            } else {
                // 离开静止，关闭静止段，进入行程
                flushStopping();
                state = XDXSegStateMoving;
                // 当前点作为下一候选静止窗口的起点
                [pending removeAllObjects];
                anchor = p;
                [pending addObject:p];
                stopCenter = nil;
            }
        }

        lastTime = t;
    }

    // 扫描结束收尾
    if (state == XDXSegStateStop) {
        flushStopping();
    } else {
        // 未成静止的候选加入行程并收尾
        drainPendingToMoving();
        flushMoving();
    }

    if (segments.count == 0) {
        return @[].mutableCopy;
    }

    // 2) 末端去抖：合并过短行程段（<2分钟 或 <200米）
    // 计算段的持续时间与距离
    double (^segmentDistanceKm)(NSArray<NSDictionary *> *) = ^double(NSArray<NSDictionary *> *seg) {
        if (seg.count < 2) return 0.0;
        double total = 0.0;
        for (NSInteger i = 1; i < seg.count; i++) {
            NSDictionary *a = seg[i-1];
            NSDictionary *b = seg[i];
            total += [TrackTool distanceBetweenOrderByLatitudeA:[a[@"lat"] doubleValue]
                                                    latitudeB:[b[@"lat"] doubleValue]
                                                    longitudeA:[a[@"lon"] doubleValue]
                                                    longitudeB:[b[@"lon"] doubleValue]];
        }
        return total;
    };
    NSTimeInterval (^segmentDuration)(NSArray<NSDictionary *> *) = ^NSTimeInterval(NSArray<NSDictionary *> *seg) {
        if (seg.count == 0) return 0;
        return [seg.lastObject[@"t"] doubleValue] - [seg.firstObject[@"t"] doubleValue];
    };

    NSInteger idx = 0;
    while (idx < segments.count) {
        if ([types[idx] isEqualToString:@"trip"]) {
            NSArray *seg = segments[idx];
            NSTimeInterval dur = segmentDuration(seg);
            double dist = segmentDistanceKm(seg);
            BOOL tooShort = (dur < minTripDurationSec) || (dist < minTripDistanceKm);
            if (tooShort) {
                BOOL hasLeft = (idx - 1) >= 0;
                BOOL hasRight = (idx + 1) < segments.count;
                if (hasLeft && hasRight && [types[idx-1] isEqualToString:@"stop"] && [types[idx+1] isEqualToString:@"stop"]) {
                    // 左停 + 短行程 + 右停 => 合并为一段静止
                    NSMutableArray *merged = [NSMutableArray arrayWithArray:segments[idx-1]];
                    [merged addObjectsFromArray:segments[idx]];
                    [merged addObjectsFromArray:segments[idx+1]];
                    [segments replaceObjectsInRange:NSMakeRange(idx-1, 3) withObjectsFromArray:@[merged]];
                    [types replaceObjectsInRange:NSMakeRange(idx-1, 3) withObjectsFromArray:@[@"stop"]];
                    idx = MAX(idx-1, 0);
                    continue;
                } else if (hasLeft && [types[idx-1] isEqualToString:@"stop"]) {
                    // 并入左侧静止
                    NSMutableArray *left = [segments[idx-1] mutableCopy];
                    [left addObjectsFromArray:segments[idx]];
                    [segments replaceObjectsInRange:NSMakeRange(idx-1, 2) withObjectsFromArray:@[left]];
                    [types replaceObjectsInRange:NSMakeRange(idx-1, 2) withObjectsFromArray:@[@"stop"]];
                    idx = MAX(idx-1, 0);
                    continue;
                } else if (hasRight && [types[idx+1] isEqualToString:@"stop"]) {
                    // 并入右侧静止
                    NSMutableArray *merged = [NSMutableArray arrayWithArray:segments[idx]];
                    [merged addObjectsFromArray:segments[idx+1]];
                    [segments replaceObjectsInRange:NSMakeRange(idx, 2) withObjectsFromArray:@[merged]];
                    [types replaceObjectsInRange:NSMakeRange(idx, 2) withObjectsFromArray:@[@"stop"]];
                    continue;
                } else if (hasLeft) {
                    // 合并进左侧行程
                    NSMutableArray *left = [segments[idx-1] mutableCopy];
                    [left addObjectsFromArray:segments[idx]];
                    [segments replaceObjectsInRange:NSMakeRange(idx-1, 2) withObjectsFromArray:@[left]];
                    [types replaceObjectsInRange:NSMakeRange(idx-1, 2) withObjectsFromArray:@[types[idx-1]]];
                    idx = MAX(idx-1, 0);
                    continue;
                } else if (hasRight) {
                    // 合并进右侧行程
                    NSMutableArray *merged = [NSMutableArray arrayWithArray:segments[idx]];
                    [merged addObjectsFromArray:segments[idx+1]];
                    [segments replaceObjectsInRange:NSMakeRange(idx, 2) withObjectsFromArray:@[merged]];
                    [types replaceObjectsInRange:NSMakeRange(idx, 2) withObjectsFromArray:@[types[idx+1]]];
                    continue;
                }
            }
        }
        idx++;
    }

    // 3) 产出：返回二维 segments（每点为原对象的拷贝），并在拷贝上设置 activity
    NSMutableArray<NSArray<NSDictionary *> *> *result = [NSMutableArray arrayWithCapacity:segments.count];
    for (NSInteger si = 0; si < segments.count; si++) {
        NSArray<NSDictionary *> *seg = segments[si];
        NSString *type = types[si]; // "stop" / "trip"
        NSString *typeCN = [type isEqualToString:@"stop"] ? @"静止" : @"行程";

        // 如果该段为“行程”，且段内任一点原始 activity 为“驾车”，则整段标记为“驾车”
        NSString *finalTypeCN = typeCN;
//        if ([typeCN isEqualToString:@"行程"]) {
//            BOOL containsDrive = NO;
//            for (NSDictionary *pt in seg) {
//                NSDictionary *orig = pt[@"orig"];
//                if ([orig isKindOfClass:[NSDictionary class]]) {
//                    id act = orig[@"activity"];
//                    if ([act isKindOfClass:[NSString class]] && [(NSString *)act isEqualToString:@"驾车"]) {
//                        containsDrive = YES;
//                        break;
//                    }
//                }
//            }
//            if (containsDrive) { finalTypeCN = @"驾车"; }
//        }
        NSMutableArray<NSDictionary *> *outSeg = [NSMutableArray arrayWithCapacity:seg.count];
        for (NSDictionary *pt in seg) {
            NSDictionary *orig = pt[@"orig"];
            if (orig) {
                NSMutableDictionary *mut = [orig mutableCopy];
                // 保存原始的activity值到org_activity字段
                id originalActivity = orig[@"activity"];
                if (originalActivity) {
                    mut[@"org_activity"] = originalActivity;
                }
                mut[@"activity"] = finalTypeCN;
                [outSeg addObject:mut];
            }
        }
        if (outSeg.count > 0) { [result addObject:outSeg]; }
    }
    return result;
}

+ (NSMutableArray<NSDictionary *> *)xdxFilterSpikePoints:(NSMutableArray<NSDictionary *> *)sortedPoints
{
    if (sortedPoints.count <= 2) { return sortedPoints; }
    
    const double spikeRadiusKm = 0.50;       // 判定异常尖刺的最小距离阈值（约500米）
    const double clusterRadiusKm = 0.15;     // 正常簇半径（约150米，用来判断回归同一片区域）
    NSMutableArray<NSDictionary *> *clean = [NSMutableArray arrayWithCapacity:sortedPoints.count];
    
    // 先保留第一个点，稍后再做首尾复检
    [clean addObject:sortedPoints.firstObject];
    
    for (NSInteger i = 1; i < sortedPoints.count - 1; i++) {
        NSDictionary *prev = clean.lastObject;        // 实际已保留的上一点
        NSDictionary *curr = sortedPoints[i];
        NSDictionary *next = sortedPoints[i + 1];
        
        double dPrevCurr = [TrackTool distanceBetweenOrderByLatitudeA:[prev[@"lat"] doubleValue]
                                                            latitudeB:[curr[@"lat"] doubleValue]
                                                            longitudeA:[prev[@"lon"] doubleValue]
                                                            longitudeB:[curr[@"lon"] doubleValue]];
        double dCurrNext = [TrackTool distanceBetweenOrderByLatitudeA:[curr[@"lat"] doubleValue]
                                                            latitudeB:[next[@"lat"] doubleValue]
                                                            longitudeA:[curr[@"lon"] doubleValue]
                                                            longitudeB:[next[@"lon"] doubleValue]];
        double dPrevNext = [TrackTool distanceBetweenOrderByLatitudeA:[prev[@"lat"] doubleValue]
                                                            latitudeB:[next[@"lat"] doubleValue]
                                                            longitudeA:[prev[@"lon"] doubleValue]
                                                            longitudeB:[next[@"lon"] doubleValue]];
        
        BOOL looksLikeSpike = (dPrevCurr > spikeRadiusKm && dCurrNext > spikeRadiusKm && dPrevNext < clusterRadiusKm);
        
        if (looksLikeSpike) {
            // 进一步向后看两点，确认轨迹确实回到 prev 所在簇
            BOOL rejoinCluster = YES;
            NSInteger lookaheadSteps = MIN(2, sortedPoints.count - i - 1);
            for (NSInteger k = 1; k <= lookaheadSteps; k++) {
                NSDictionary *future = sortedPoints[i + k];
                double dFuturePrev = [TrackTool distanceBetweenOrderByLatitudeA:[future[@"lat"] doubleValue]
                                                                       latitudeB:[prev[@"lat"] doubleValue]
                                                                       longitudeA:[future[@"lon"] doubleValue]
                                                                       longitudeB:[prev[@"lon"] doubleValue]];
                if (dFuturePrev > clusterRadiusKm) {
                    rejoinCluster = NO;
                    break;
                }
            }
            if (rejoinCluster) {
                continue; // 丢弃 curr
            }
        }
        
        [clean addObject:curr];
    }
    
    [clean addObject:sortedPoints.lastObject];
    
    // 对首尾再做一次孤点复检
    if (clean.count >= 2) {
        NSDictionary *first = clean.firstObject;
        NSDictionary *second = clean[1];
        double dFirstSecond = [TrackTool distanceBetweenOrderByLatitudeA:[first[@"lat"] doubleValue]
                                                               latitudeB:[second[@"lat"] doubleValue]
                                                               longitudeA:[first[@"lon"] doubleValue]
                                                               longitudeB:[second[@"lon"] doubleValue]];
        if (dFirstSecond > spikeRadiusKm) {
            [clean removeObjectAtIndex:0];
        }
        
        NSDictionary *last = clean.lastObject;
        NSDictionary *penultimate = clean[clean.count - 2];
        double dLastPenultimate = [TrackTool distanceBetweenOrderByLatitudeA:[last[@"lat"] doubleValue]
                                                                    latitudeB:[penultimate[@"lat"] doubleValue]
                                                                    longitudeA:[last[@"lon"] doubleValue]
                                                                    longitudeB:[penultimate[@"lon"] doubleValue]];
        if (dLastPenultimate > spikeRadiusKm) {
            [clean removeLastObject];
        }
    }
    
    return clean;
}

@end
